package com.cy.pj.sys.service.impl;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.cy.pj.common.exception.ServiceException;
import com.cy.pj.common.pojo.Node;
import com.cy.pj.sys.dao.SysMenuDao;
import com.cy.pj.sys.dao.SysRoleMenuDao;
import com.cy.pj.sys.dao.SysUserRoleDao;
import com.cy.pj.sys.pojo.SysMenu;
import com.cy.pj.sys.pojo.SysUserMenu;
import com.cy.pj.sys.service.SysMenuService;

@Service
public class SysMenuServiceImpl implements SysMenuService {


	@Autowired
	private SysMenuDao sysMenuDao;
	
	@Autowired
	private SysRoleMenuDao sysRoleMenuDao;
	
	@Autowired
	private SysUserRoleDao sysUserRoleDao;
	
	
	/**
	 * 查询所有的菜单信息
	 */
	//@Cacheable 对象用户告诉spring框架,目标方法的返回值应存储到cache对象。
	@Cacheable(value = "menuCache")	//menuCache为缓存对象的名称(自己随意取)
	@Override
	public List<Map<String, Object>> findObjects() {
		System.out.println("测试cache是否被调用");
		List<Map<String, Object>> list = sysMenuDao.findObjects();
		if(list==null||list.size()==0)
			throw new ServiceException("没有对应的菜单信息");
		return list;
	}

	
	/**
	 * 删除菜单，并校验信息
	 */
	@CacheEvict(value = "menuCache",allEntries = true,beforeInvocation = false)
	@Override
	public int deleteObject(Integer id) {
		//先校验参数
		if(id==null||id<=0)
			throw new IllegalArgumentException("请先选择需要删除的菜单");
		//统计菜单中是否还存在子元素
		int count = sysMenuDao.getChildCount(id);
		//查询出来的记录大于0便是有子菜单，此时不允许删除
		if(count>0)
			throw new ServiceException("请先删除子菜单");
		//删除角色和菜单关系数据
		sysRoleMenuDao.deleteObjectsByMenuId(id);
		//再删除自身的菜单信息
		int rows = sysMenuDao.deleteObject(id);
		if(rows==0)
			throw new ServiceException("此菜单可能已被删除");
		return rows;
	}

	
	//添加新菜单时点击上级菜单呈现所有的菜单供用户选择
	@Override
	public List<Node> findZtreeMenuNodes() {
		return sysMenuDao.findZtreeMenuNodes();
	}


	/**
	 * 新增菜单
	 */
	@CacheEvict(value = "menuCache",allEntries = true,beforeInvocation = false)
	@Override
	public int saveObject(SysMenu entity) {
		//校验用户是否填写信息
		if(entity==null)
			throw new IllegalArgumentException("保存对象不能为空");
		//获取用户是否输入菜单名称
		if(StringUtils.isEmpty(entity.getName()))
			throw new IllegalArgumentException("菜单名不能为空");
		int rows;
		//保存菜单信息，写入数据库
		try {
			rows=sysMenuDao.insertObject(entity);
		} catch (Exception e) {
			e.printStackTrace();
			throw new ServiceException("保存失败，请稍后再试");
		}
		return rows;
	}

	
	/**
	 * 修改菜单
	 * @CacheEvict 此注解表示在方法业务执行过程中要清除缓存
	 * value属性：用来指定要清除的缓存对象
	 * allEntries属性：表示要清除缓存对象中的所有数据
	 * beforeInvocation属性：true表示在方法执行之前执行，false表示在方法执行之后执行
	 */
	@CacheEvict(value = "menuCache",allEntries = true,beforeInvocation = false)
	@Override
	public int updataObjecs(SysMenu entity) {
		//校验基本参数
		if(entity==null)
			throw new IllegalArgumentException("请填写需要修改的内容");
		if(StringUtils.isEmpty(entity.getName()))
			throw new IllegalArgumentException("菜单名不能为空");
		//执行更新操作
		int rows = sysMenuDao.updateObject(entity);
		if(rows==0)
			throw new IllegalArgumentException("修改失败，记录可能已经被删除");
		return rows;
	}


	//用户有什么权限就给他展示什么内容
	@Override
	public List<SysUserMenu> findUserMenusByUserId(Integer id) {
		//1.基于用户id获取用户对应的角色id
		List<Integer> roleIds = sysUserRoleDao.findRoleIdsByUserId(id);
		//2.基于角色id获取角色对应的菜单id
		List<Integer> menuIds = sysRoleMenuDao.findMenuIdsByRoleIds(roleIds);
		//3.基于菜单id获取对应的菜单信息(一级和二级菜单)
		List<SysUserMenu> userMenus = sysMenuDao.findMenusByIds(menuIds);
		return userMenus;
	}

}
